Next | Prev | Up | Top | Contents | Index
Memory Use in Kernel-Level Drivers
When you control a device from a kernel-level driver, your code executes in kernel virtual space. The allocation of memory for program text, local (stack) variables, and static global variables is handled automatically by the kernel. Besides designing data structures so they have a consistent size, you have to consider these special cases:
- dynamic memory allocation for data and for buffers
- getting addresses of device registers for the device you control
- transferring data between kernel space and user process space
The kernel supplies utility functions to help you deal with each of these issues, all of which are discussed in Chapter 9, "Device Driver/Kernel Interface."
Uncached Memory Access in the Challenge and Onyx Series
Access to uncached memory is not supported. The Challenge and Onyx systems have coherent caches; cache coherency is maintained by the hardware, even under access from CPUs and concurrent DMA. There is never a need (and no approved way) to access uncached memory in these systems.
Note: In certain specific hardware configurations, a device driver may have to deal with cache issues in a Challenge or Onyx system. See Appendix B, "Challenge DMA with Multiple IO4 Boards."
Uncached Memory Access in the IP26 CPU
The IP26 CPU module is used in the Silicon Graphics Power Indigo2 workstation and the Power Challenge M workstation. Both are deskside workstations using the R8000 processor chip.
Late in the design of these systems, the parity-based memory that had been planned for them was replaced with ECC memory (error-correcting code memory, which can correct for single-bit errors on the fly). ECC memory is also used in large multiprocessor systems from Silicon Graphics, where it has no effect on performance.
Owing to the hardware design of the IP26, ECC memory could be added with no impact on the performance of cached memory access, but uncached memory access can be permitted only when the CPU is placed in a special, "slow" access mode.
In some cases a kernel-level device driver must be sure that stored data has been written into main memory, rather than being held in the cache. There are two ways to ensure this:
- Store the data into cached memory, then use the dki_dcache_wb() function to force a range of cached addresses to be written to memory. This method works in all systems including the IP26; however, the function call is an expensive one when the amount of data is small.
- Write directly to uncached memory using addresses in kseg1. This works in all systems, but in the IP26 (only) it will fail unless the CPU is first put into "slow" mode.
In order to put the CPU into "slow" mode, call the function ip26_enable_ucmem(). As soon as the uncached store is complete, return the system to "fast" mode by calling ip26_return_ucmem(). (See the ip26_ucmem(D3) reference page.) While the CPU is in "slow" mode, several clock cycles are added to every memory access, so do not keep it in "slow" mode any longer than necessary.
These functions can be called in any system. They do nothing unless the CPU is an IP26. Alternatively, you could save the current CPU type using a function like the one shown in Example 2-2, and call the functions only when that function returns INV_IP26BOARD.
Next | Prev | Up | Top | Contents | Index